// DropletPrograms.cpp

#include "DropletPrograms.h"

extern std::map<uint16_t, bool> _killSwitches;
extern bool _verbose;
extern sem_t _lock;
extern uint16_t _activeDropletID;

using namespace Droplets;

// Each of these functions should be considered as the main() function in AVR-gcc code.
// Only 1 of these programs will be loaded onto a given robot at the beginning of each
// simulation and can not be changed once the simulator has started running.
void *Droplets::Program1(void *obj)
{

	uint16_t robotID;

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	DropletThreadData *dPtr = (DropletThreadData *)obj;
	robotID = dPtr->dropletID;
#endif
// ============================================================================

// *** SIMULATOR - Non-Critcal Section init code can go here... ***


// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_wait(&_lock);
	_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section init code goes here... ***
	InitDroplet();
	SetupIRSensors();
	SetupRGBSensor();
	SetupComm(robotID); // Very Important! This sets the robot ID 
	SetupLEDs();
	SetupMotors();

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_post(&_lock);
#endif
// ============================================================================

	while(1)
	{

// *** SIMULATOR - Non-Critcal Section main loop code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_wait(&_lock);
		_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section main loop code goes here... ***
		if(!IsMoving())
		{
			Move(Random(360), 5, 3);
		}

// This is simulator specific code for terminating the thread. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_post(&_lock);
		if(_killSwitches.find(dPtr->dropletID)->second)
		{
			// close up everything and return from the thread.
			break;
		}
#endif
// ============================================================================
	}

	return NULL;
}




void *Droplets::Program2(void *obj)
{

	uint16_t robotID;

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	DropletThreadData *dPtr = (DropletThreadData *)obj;
	robotID = dPtr->dropletID;
#endif
// ============================================================================

// *** SIMULATOR - Non-Critcal Section init code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_wait(&_lock);
	_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section init code goes here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_post(&_lock);
#endif
// ============================================================================

	while(1)
	{
// *** SIMULATOR - Non-Critcal Section main loop code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_wait(&_lock);
		_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section main loop code goes here... ***

// This is simulator specific code for terminating the thread. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_post(&_lock);
		if(_killSwitches.find(dPtr->dropletID)->second)
		{
			// close up everything and return from the thread.
			break;
		}
#endif
// ============================================================================
	}

	return NULL;
}




void *Droplets::Program3(void *obj)
{
	uint16_t robotID;

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	DropletThreadData *dPtr = (DropletThreadData *)obj;
	robotID = dPtr->dropletID;
#endif
// ============================================================================

// *** SIMULATOR - Non-Critcal Section init code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_wait(&_lock);
	_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section init code goes here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_post(&_lock);
#endif
// ============================================================================

	while(1)
	{
// *** SIMULATOR - Non-Critcal Section main loop code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_wait(&_lock);
		_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section main loop code goes here... ***

// This is simulator specific code for terminating the thread. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_post(&_lock);
		if(_killSwitches.find(dPtr->dropletID)->second)
		{
			// close up everything and return from the thread.
			break;
		}
#endif
// ============================================================================
	}

	return NULL;
}




void *Droplets::Program4(void *obj)
{
	uint16_t robotID;

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	DropletThreadData *dPtr = (DropletThreadData *)obj;
	robotID = dPtr->dropletID;
#endif
// ============================================================================

// *** SIMULATOR - Non-Critcal Section init code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_wait(&_lock);
	_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section init code goes here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_post(&_lock);
#endif
// ============================================================================

	while(1)
	{
// *** SIMULATOR - Non-Critcal Section main loop code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_wait(&_lock);
		_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section main loop code goes here... ***

// This is simulator specific code for terminating the thread. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_post(&_lock);
		if(_killSwitches.find(dPtr->dropletID)->second)
		{
			// close up everything and return from the thread.
			break;
		}
#endif
// ============================================================================
	}

	return NULL;
}




void *Droplets::Program5(void *obj)
{
	uint16_t robotID;

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	DropletThreadData *dPtr = (DropletThreadData *)obj;
	robotID = dPtr->dropletID;
#endif
// ============================================================================

// *** SIMULATOR - Non-Critcal Section init code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_wait(&_lock);
	_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section init code goes here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
	sem_post(&_lock);
#endif
// ============================================================================

	while(1)
	{
// *** SIMULATOR - Non-Critcal Section main loop code can  go here... ***

// This is simulator specific code for thread handling. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_wait(&_lock);
		_activeDropletID = robotID;
#endif
// ============================================================================

// *** SIMULATOR - Critical Section main loop code goes here... ***

// This is simulator specific code for terminating the thread. 
// DO NOT EDIT BETWEEN THE DOUBLE LINES!
// ============================================================================
#ifdef _WIN32
		sem_post(&_lock);
		if(_killSwitches.find(dPtr->dropletID)->second)
		{
			// close up everything and return from the thread.
			break;
		}
#endif
// ============================================================================
	}

	return NULL;
}
